package com.mt.roll.core.utils;

import com.mt.roll.core.base.IErrorCode;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
 * <p>Title:跟时间有关的便利方法 DateUtil.java</p>
 */
public class DateUtil {
    /**
     * 一秒中的等价毫秒数
     */
    public static final long SECOND = 1000;
    /**
     * 一分钟的等价毫秒数
     */
    public static final long MINUTE = 60 * SECOND;
    /**
     * 一小时的等价毫秒数
     */
    public static final long HOUR = 60 * MINUTE;
    /**
     * 一天的等价毫秒数
     */
    public static final long DAY = 24 * HOUR;
    /**
     * 半小时的等价毫秒数
     */
    public static final long HALF_HOUR = HOUR / 2;

    /**
     * 格式化日期（yyyyMM）
     */
    public static final String MONTH_DATEPATTERN = "yyyyMM";

    /**
     * 格式化日期（yyyyMMdd）
     */
    public static final String SHORT_DATEPATTERN = "yyyyMMdd";
    /**
     * 格式化日期（yyyy-MM-dd hh:mm:ss）
     */
    public static final String DEFAULT_DATEPATTERN = "yyyy-MM-dd hh:mm:ss";
    /**
     * 格式化日期（yyyy-MM-dd HH:mm:ss）
     */
    public static final String DEFAULT_DATESFM = "yyyy-MM-dd HH:mm:ss";
    /**
     * 格式化日期（yyyy-MM-dd HH:mm）
     */
    public static final String DEFAULT_MINUS = "yyyy-MM-dd HH:mm";
    /**
     * 格式化日期（yyyy-MM-dd）
     */
    public static final String SAMPLE_DATEPATTERN = "yyyy-MM-dd";

    public static final String YEAR_DATEPATTERN = "yyyy";
    /**
     * 格式化日期（yyyyMMdd）
     */
    public static final String SHORT_DATE_PATTERN = "yyyyMMdd";
    /**
     * 格式化日期(yyyy年MM月dd日)
     */
    public static final String SHORT_CHAR_DATE_PATTERN = "yyyy年MM月dd日";
    /**
     * 格式化日期（HHmmss）
     */
    public static final String StR_PATTERN_HHMMSS = "HHmmss";
    /**
     * 格式化时间（HH:mm:ss）
     */
    public static final String StR_PATTERN_HHMMSS1 = "HH:mm:ss";
    public static final String StR_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    /**
     * 格式：yyyyMMdd，8位
     */
    public static final String PATTERN_NUM_DATE = "yyyyMMdd";
    /**
     * 格式：yyyyMMddHHmmss，14位
     */
    public static final String PATTERN_NUM_SEC = "yyyyMMddHHmmss";
    /**
     * 格式：yyyyMMddHHmmssSSS，17位
     */
    public static final String PATTERN_NUM_MS = "yyyyMMddHHmmssSSS";

    public static final String PATTERN_NUM_MS_ELSE = "yyyy/MM/dd HH:mm:ss";
    /**
     * 格式化日期（yyyyMMddHHmmss）
     */
    public static String STR_PATTERN = "yyyyMMddHHmmss";

    public DateUtil() {
    }

    public static String defaultFormat(Date date) {
        return new SimpleDateFormat(SAMPLE_DATEPATTERN).format(date);
    }

    /**
     * 获取今天凌晨的0分0秒这个时间
     */
    public static Date getDayBegin() {

        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static boolean isTowTimeAvailable(LocalDateTime time1,LocalDateTime time2){
        if(time1 == null || time2 == null){
            return false;
        }
        if(time1.compareTo(time2)>0 ){
            return false;
        }
        return true;
    }

    /**
     * 获取昨天凌晨的0分0秒这个时间
     */
    public static Date getYesterdayDayBegin() {

        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, -1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    /**
     * 获取指定日期凌晨的0分0秒这个时间
     *
     * @param date
     * @return
     */
    public static Date getBegin(Date date) {
        String dateStr = DateUtil.shortDateString(date, SHORT_DATE_PATTERN);
        Date dayBegin = DateUtil.shortStringToDate(dateStr, SHORT_DATE_PATTERN);
        return dayBegin;
    }

    /**
     * 判断是否是周末。是则返回true,否则返回false
     */
    public static boolean isWeekEnd() {
        Calendar cal = Calendar.getInstance();
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否是星期一，是则返回true,否则返回false
     */
    public static boolean isWeekStart() {
        Calendar cal = Calendar.getInstance();
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否是一号，是则返回true,否则返回false
     */
    public static boolean isMonthStart() {
        Calendar cal = Calendar.getInstance();
        if (cal.get(Calendar.DAY_OF_MONTH) == 1) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否是月末，是则返回true,否则返回false
     */
    public static boolean isMonthEnd() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, 1);
        if (cal.get(Calendar.DAY_OF_MONTH) == 1) {
            return true;
        }
        return false;
    }

    /**
     * @return 返回明天凌晨0点0分0秒
     */
    public static Date getNextDay() {
        return getNextHour(0);
    }

    /**
     * @return 返回指定时间(x点整)最靠近的时间, 如果今天已经过了那个时间, 则返回明天的那个时间
     * 否则返回今天的那个整点时间
     */
    public static Date getNextHour(int hour) {
        return getNextTime(hour, 0);
    }

    /**
     * @param hour 几点
     * @param min  几分
     * @return 获得指定时间(x点y分)最靠近的时间, 如果今天已经过了那个时间, 则返回明天的那个时间
     * 否则返回今天的那个时间
     */
    public static Date getNextTime(int hour, int min) {
        Calendar calendar = Calendar.getInstance();
        if (calendar.get(Calendar.HOUR_OF_DAY) > hour) {
            calendar.add(Calendar.DATE, 1);
        } else if (calendar.get(Calendar.HOUR_OF_DAY) == hour &&
                calendar.get(Calendar.MINUTE) >= min) {
            calendar.add(Calendar.DATE, 1);
        }

        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, min);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定的日期
     *
     * @param year  年
     * @param month 月
     * @param day   日
     * @param hour  小时
     * @param min   分
     * @return
     */
    public static Date getTime(int year, int month, int day, int hour, int min) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DATE, day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, min);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取月初的时间
     *
     * @return
     */
    public static Date getMonthBenin() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取当前月份+month月初时间，时间为  00:00:00
     *
     * @return
     */
    public static Date getNextMonthBeginTime(int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR, 12);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取相继几天的时间
     *
     * @param before
     * @return
     */
    public static Date getDayBefore(int before) {
        return getDayBefore(null, before);
    }

    public static Date getDayBefore(Date date, int before) {
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        }

        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - before);
        return calendar.getTime();
    }

    /**
     * 获取date之前或之后number天的日期
     *
     * @param date
     * @param number 正数 当前日期之后   负数：当前日期之前
     * @return
     */
    public static Date getAfterOrBeforeDay(Date date, int number) {
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        }
        calendar.add(Calendar.DAY_OF_MONTH, number);
        return calendar.getTime();
    }

    /**
     * 获取当前日期之前或之后number天的日期
     *
     * @param date
     * @param number 正数 当前日期之后   负数：当前日期之前
     * @return
     */
    public static Date getAfterOrBeforeDay(int number) {
        return getAfterOrBeforeDay(new Date(), number);
    }

    public static String shortDateString(Date date) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(SAMPLE_DATEPATTERN);
        return sdf.format(date);
    }

    /**
     * 按照格式返回日期字符串
     *
     * @param date
     * @param format (如：yyyyMMdd )
     * @return
     */
    public static String shortDateString(Date date, String format) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 根据时间字串和格式化标准进行格式化
     *
     * @param dateStr {String} 时间字串
     * @param format  {String} 格式化标准 【exam:'yyyy-MM-dd hh:mm:ss'】
     * @return {java.util.Date}
     */
    public static Date shortStringToDate(String dateStr, String format) {
        Date date = null;

        if (null == dateStr) {
            date = new Date();
        } else {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                date = sdf.parse(dateStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return date;
    }

    public static Date shortStringToDate(String dateStr) {
        return shortStringToDate(dateStr, SAMPLE_DATEPATTERN);
    }

    public static Date shortStringToDateFormat(String dateStr, String format) {
        return shortStringToDate(dateStr, format);
    }

    /**
     * 将不同类型的日期格式转成yyyy-MM-dd格式字符串
     *
     * @param date
     * @param format (如：yyyyMMdd )
     * @return
     */
    public static String shortDateString(String date, String format) {
        if (date == null) {
            return "";
        }
//    	SimpleDateFormat sdf = new SimpleDateFormat(format);
        return shortDateString(shortStringToDate(date, format));
    }

    /**
     * 计算2个日期的间隔的秒数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static long elapsedSecond(Date d1, Date d2) {
        long d = Math.abs(d1.getTime() - d2.getTime());
        return d / 1000;
    }

    /**
     * 计算2个日期间隔的分钟数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static long elapsedMinute(Date d1, Date d2) {
        return elapsedSecond(d1, d2) / 60;
    }

    /**
     * 计算2个日期间隔的小时数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static long elapsedhour(Date d1, Date d2) {
        return elapsedMinute(d1, d2) / 60;
    }

    public static long elapsedMonth(Date d1, Date d2) {
        return elapsedDay(d1, d2) / 30;
    }

    /**
     * 计算2个日期间隔的天数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static int elapsedDay(Date d1, Date d2) {
        return (int) elapsedhour(d1, d2) / 24;
    }

    /**
     * 计算2个日期间隔的年数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static Double elapsedYear(Date d1, Date d2) {
        return new Double(elapsedDay(d1, d2) / 365.0);
    }

    /**
     * 获取当前月-number的日期
     *
     * @param number
     * @return
     */
    public static Date getDateBeforeOfMonth(int number) {
        Calendar now = Calendar.getInstance();
        now.setTime(new Date());
        now.set(Calendar.MONTH, now.get(Calendar.MONTH) - number);
        return now.getTime();
    }

    public static String simpleFormat(Date date) {
        return new SimpleDateFormat(SHORT_DATE_PATTERN).format(date);
    }

    /**
     * 获取当前月-number的日期
     *
     * @param number
     * @return
     */
    public static Date getDateBeforeOfMonth(Date date, int number) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.MONTH, now.get(Calendar.MONTH) - number);
        return now.getTime();
    }

    /**
     * 获取当前月+number的日期
     *
     * @param month
     * @return
     */
    public static Date getDateAfterOfMonth(int month) {
        Calendar now = Calendar.getInstance();
        now.setTime(new Date());
        now.set(Calendar.MONTH, now.get(Calendar.MONTH) + month);
        return now.getTime();
    }

    /**
     * 获取月+number的日期
     *
     * @param month
     * @return
     */
    public static Date getDateAfterOfMonth(Date date, int month) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.MONTH, now.get(Calendar.MONTH) + month);
        return now.getTime();
    }

    /**
     * 获取当前年+number的日期
     *
     * @param year
     * @return
     */
    public static Date getDateAfterOfYear(int year) {
        Calendar now = Calendar.getInstance();
        now.setTime(new Date());
        now.set(Calendar.YEAR, now.get(Calendar.YEAR) + year);
        return now.getTime();
    }

    /**
     * 获取年+number的日期
     *
     * @param year
     * @return
     */
    public static Date getDateAfterOfYear(Date date, int year) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.YEAR, now.get(Calendar.YEAR) + year);
        return now.getTime();
    }

    /**
     * 获得2个日期之间的时间间隔
     *
     * @param da1(起始日期 格式：yyyy yyyyMM yyyyMMdd)
     * @param da2(截止日期)
     * @return
     */
    public static String getTimeBetweenDates(String da1, String da2) {
        String str = "";
        if (StringUtils.isEmpty(da1) || StringUtils.isEmpty(da2) || !StringUtils.isNumeric(da1) || !StringUtils.isNumeric(da2) || "19000101".equals(da1)) {
            return "--";
        }
        Date now = new Date();
        int years = 0;
        int months = 0;
        if (da1.length() == 4 || da2.length() == 4) {
            String dateStr1 = da1.substring(0, 4);
            String dateStr2 = da2.substring(0, 4);
            years = Integer.valueOf(dateStr2) - Integer.valueOf(dateStr1);
            str = years + "年";
        } else if (da1.length() == 6 || da2.length() == 6) {
            String yearStr1 = da1.substring(0, 4);
            String yearStr2 = da2.substring(0, 4);
            years = Integer.valueOf(yearStr2) - Integer.valueOf(yearStr1);
            String monthStr1 = da1.substring(4, 6);
            String monthStr2 = da2.substring(4, 6);
            months = Integer.valueOf(monthStr2) - Integer.valueOf(monthStr1);
            if (months < 0) {
                years = years - 1;
                months = months + 12;
            }
            if (years > 0) {
                str = years + "年";
            }
            if (months > 0) {
                str = str + months + "月";
            }
        } else {
            str = getTimeBetweenDates(shortStringToDate(da1, "yyyyMMdd"), shortStringToDate(da2, "yyyyMMdd"));
        }
        return str;
    }
    //LocalDateTime -> Date
    public static Date asDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 验证两个时间段是否存在交集
     * leftStart  选中开始时间
     * leftEnd    选中结束时间
     *
     * rightStart 待比较开始时间
     * rightEnd   待比较结束时间
     *
     * return  true  （存在交集）
     * return  false （不存在交集）
     *
     * */
    public static boolean timeCoincides(LocalDateTime leftStart,LocalDateTime leftEnd,LocalDateTime rightStart,LocalDateTime rightEnd){

        /* 开始时间 */
        Date leftStartDate = asDate(leftStart);
        /* 结束时间 */
        Date leftEndDate = asDate(leftEnd);
        /*比较的时间段*/
        Date rightStartDate = asDate(rightStart);
        Date rightEndDate = asDate(rightEnd);
        /*判断*/
        if (((leftStartDate.getTime() >= rightStartDate.getTime())
                && leftStartDate.getTime() < rightEndDate.getTime())
                || ((leftStartDate.getTime() > rightStartDate.getTime())
                && leftStartDate.getTime() <= rightEndDate.getTime())
                || ((rightStartDate.getTime() >= leftStartDate.getTime())
                && rightStartDate.getTime() < leftEndDate.getTime())
                || ((rightStartDate.getTime() > leftStartDate.getTime())
                && rightStartDate.getTime() <= leftEndDate.getTime())) {
            return true;
        }
        return false;
    }

    /**
     * 获得2个日期之间的时间间隔（如：1年124天）
     *
     * @param da1
     * @param da2
     * @return
     */
    public static String getTimeBetweenDates(Date da1, Date da2) {
        String str = "";
        if (da1 == null || da2 == null || "19000101".equals(da1)) {
            return "--";
        }
        if (da1.getTime() > da2.getTime()) {
            return getTimeBetweenDates(da2, da1);
        } else {
            int year1 = da1.getYear();
            int year2 = da2.getYear();
            if (year1 == year2) {
                int days = elapsedDay(da1, da2);
                str = days + "天";
            } else {
                int years = year2 - year1 - 1;
                Date date1 = new Date();
                date1.setYear(da1.getYear());
                date1.setMonth(11);
                date1.setDate(31);
                int days1 = elapsedDay(da1, date1);
                Date date2 = new Date();
                date2.setYear(da2.getYear());
                date2.setMonth(0);
                date2.setDate(1);
                int days2 = elapsedDay(date2, da2) + 1;
                int days = days1 + days2;
                if (days >= 365) {
                    days = days - 365;
                    years++;
                }
                if (years > 0) {
                    str = years + "年";
                }
                if (days > 0) {
                    str = str + days + "天";
                }

            }

        }
        return str;
    }

    /**
     * 获取前几个季度的日期
     *
     * @return
     */
    public static List<String> getQuarter(int length, int number) {
        List<String> list = new ArrayList<String>();
        String[] dateStr = {"0331", "0630", "0930", "1231"};
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int quarter = cal.get(Calendar.MONTH) / 3 + 1;
        quarter = quarter - number;
        //jack change 2012.1.4
        while (quarter <= 0) {
            quarter = quarter + 4;
            year = year - 1;
        }

        for (int i = 0; i < length; i++) {
            if (quarter == 1) {
                quarter = 4;
                year -= 1;
            } else {
                quarter -= 1;
            }
            list.add(year + dateStr[quarter - 1]);
        }
        return list;
    }

    /**
     * 取上季度末日期
     *
     * @param quarterDay
     * @return
     */
    public static String getLastQuarterDay(String quarterDay) {
        if ("0331".equals(quarterDay.substring(4))) {
            int year = Integer.valueOf(quarterDay.substring(0, 4)).intValue();
            return String.valueOf(year - 1) + "1231";
        } else if ("0630".equals(quarterDay.substring(4))) {
            return quarterDay.substring(0, 4) + "0331";
        } else if ("0930".equals(quarterDay.substring(4))) {
            return quarterDay.substring(0, 4) + "0630";
        } else if ("1231".equals(quarterDay.substring(4))) {
            return quarterDay.substring(0, 4) + "0930";
        }
        return null;
    }


    /**
     * 计算年龄
     *
     * @param birthday 生日日期
     * @return {int}
     */
    public static int getAge(Date birthday) {
        Calendar cal = Calendar.getInstance();
        String date = getDateTimeByPattern(SHORT_DATE_PATTERN);
        Date currentDate = strToDate(date);
        if (currentDate.before(birthday)) {
            throw new IllegalArgumentException(
                    "出生日期大于当前时间！");
        }
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH) + 1;
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthday);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH) + 1;
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        int age = yearNow - yearBirth;
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                age--;
            }
        }
        return age;
    }

    /**
     * @param datePattern
     * @return
     */
    public static String formatNowDate(String datePattern) {
        if (datePattern == null) {
            datePattern = "yyyy-MM-dd";
        }
        SimpleDateFormat df = new SimpleDateFormat(datePattern);
        return df.format(new Date());
    }

    public static String thisYearStart() {
        Calendar cal = Calendar.getInstance();
        String date = cal.get(Calendar.YEAR) + "0101";
        return date;
    }


    /**
     * 得到日期的前或者后几小时
     *
     * @param iHour 如果要获得前几小时日期，该参数为负数；
     *              如果要获得后几小时日期，该参数为正数
     * @return Date 返回参数<code>curDate</code>定义日期的前或者后几小时
     * @see Calendar#add(int, int)
     */
    public static Date getDateBeforeOrAfterHours(Date curDate, int iHour) {
        Calendar cal = Calendar.getInstance();
        if (curDate != null) {
            cal.setTime(curDate);
        }
        cal.add(Calendar.HOUR_OF_DAY, iHour);
        return cal.getTime();
    }

    public static List financeQuaterList(String year) {
        List list = new ArrayList();
        list.add(year + "0331");
        list.add(year + "0630");
        list.add(year + "0930");
        list.add(year + "1231");
        return list;
    }

    //获得周五的日期
    public static Date getFriday(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
        return c.getTime();
    }

    /**
     * 时间转换
     *
     * @param d
     * @param fmt
     * @return
     */
    public static Date parseDate(String d, String fmt) {
        SimpleDateFormat sdf = new SimpleDateFormat(fmt);
        try {
            return sdf.parse(d);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date addDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + day);
        return calendar.getTime();
    }

    /**
     * 获取相继几天的时间
     *
     * @param before
     * @return
     */
    public static Date getDayBofore(int before) {
        return getDayBofore(null, before);
    }

    public static Date getDayBofore(Date date, int before) {
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        }

        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - before);
        return calendar.getTime();
    }

    /**
     * 得到日期的前或者后几分钟
     *
     * @param min 如果要获得前几分钟时间，该参数为负数；
     *            如果要获得后几分钟时间，该参数为正数
     * @return Date 返回参数<code>curDate</code>定义日期的前或者后几分钟
     * @see Calendar#add(int, int)
     */
    public static Date getDateBeforeOrAfterMinute(Date curDate, int min) {
        Calendar cal = Calendar.getInstance();
        if (curDate != null) {
            cal.setTime(curDate);
        }
        cal.add(Calendar.MINUTE, min);
        return cal.getTime();
    }

    /**
     * 得到日期的前或者后几秒钟
     *
     * @param second 如果要获得前几秒钟时间，该参数为负数；
     *               如果要获得后几秒钟时间，该参数为正数
     * @return Date 返回参数<code>curDate</code>定义日期的前或者后几秒钟
     * @see Calendar#add(int, int)
     */
    public static Date getDateBeforeOrAfterSecond(Date curDate, int second) {
        Calendar cal = Calendar.getInstance();
        if (curDate != null) {
            cal.setTime(curDate);
        }
        cal.add(Calendar.SECOND, second);
        return cal.getTime();
    }

    /**
     * 得到当前的的年
     *
     * @return 当前的年
     */
    public static int getCurrentYear() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 根据日期得到当前季度数
     *
     * @param date format yyyyMMdd
     * @return 1:一季度；2：二季度；3：三季度；4：四季度 ；0：无
     */
    public static int getSeasonNum(String date) {
        String month = date.substring(4, 6);
        if ("01".equals(month) || "02".equals(month) || "03".equals(month)) {
            return 1;
        } else if ("04".equals(month) || "05".equals(month) || "06".equals(month)) {
            return 2;
        } else if ("07".equals(month) || "08".equals(month) || "09".equals(month)) {
            return 3;
        } else if ("10".equals(month) || "11".equals(month) || "12".equals(month)) {
            return 4;
        }
        return 0;
    }

    /**
     * 取得某个年份某个季度的季末日期
     *
     * @param year   年份
     * @param season 季度数
     * @return 季末日期，如果无，返回null
     */
    public static String getSeasonEndDate(int year, int season) {
        if (season == 1) {
            return year + "0331";
        } else if (season == 2) {
            return year + "0630";
        } else if (season == 3) {
            return year + "0930";
        } else if (season == 4) {
            return year + "1231";
        }

        return null;
    }

    /**
     * 根据日期取得当前季度季末日期
     *
     * @param date format: yyyyMMdd
     * @return String 若无，返回null
     */
    public static String getCurSeasonEndDate(String date) {
        String year = date.substring(0, 4);
        String month = date.substring(4, 6);
        if ("01".equals(month) || "02".equals(month) || "03".equals(month)) {
            return year + "0331";
        } else if ("04".equals(month) || "05".equals(month) || "06".equals(month)) {
            return year + "0630";
        } else if ("07".equals(month) || "08".equals(month) || "09".equals(month)) {
            return year + "0930";
        } else if ("10".equals(month) || "11".equals(month) || "12".equals(month)) {
            return year + "1231";
        }
        return null;
    }

    /**
     * Return an ISO 8601 combined date and time string for specified date/time
     *
     * @param date Date
     * @return String with format "yyyy-MM-dd'T'HH:mm:ss'Z'"
     */
    public static String getISO8601StringFromDate(Date date) {
        DateFormat dateFormat = new SimpleDateFormat(StR_ISO8601, Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        return dateFormat.format(date);
    }


    public static String dateToString(Date date) {
        DateFormat dateFormat = new SimpleDateFormat(DEFAULT_MINUS, Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        return dateFormat.format(date);
    }

    /**
     * 获取当前时间，精确到秒
     * 时间格式为yyyyMMddHHmmss
     *
     * @return String
     * 精确到秒的当前时间
     */
    public static String getCurrentDateTime() {
        return getDateTimeByPattern(PATTERN_NUM_SEC);
    }

    public static String getCurrentDateTimeElse() {
        return getDateTimeByPattern(DEFAULT_DATESFM);
    }

    public static String getDateTimeElse() {
        return getDateTimeByPattern(SHORT_DATEPATTERN);
    }

    public static void main(String[] args) {
        System.out.println(getDateTimeElse());
    }
    public static String getCurrentDateTimeNow() {
        return getDateTimeByPattern(SAMPLE_DATEPATTERN);
    }

    public static String getCurrentDate() {
        return getDateTimeByPattern(SHORT_DATE_PATTERN);
    }

    public static String getCurrentMonth() {
        return getDateTimeByPattern(MONTH_DATEPATTERN);
    }

    public static String getCurrentYearElse() {
        return getDateTimeByPattern(YEAR_DATEPATTERN);
    }

    /**
     * 获取当前时间，精确到毫秒
     * 时间格式为yyyyMMddHHmmssSSS
     *
     * @return String
     * 精确到毫秒的当前时间
     */
    public static String getCurrentDateTimeMs() {
        return getDateTimeByPattern(PATTERN_NUM_MS);
    }

    /**
     * 依据传入的时间格式获取当前时间
     * 比如传入的是yyyyMMdd,则获取的是精确到天的当前时间
     * 比如传入的是yyyyMMddHHmmss,则获取的是精确到秒的当前时间
     *
     * @param pattern 时间格式字符串
     * @return String
     * 符合要求的时间
     */
    public static String getDateTimeByPattern(String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(new Date());
    }

    /*
     * 获取当前时间的前一天
     */
    public static Date getBeforeDate(Date date) {
        Date dNow = new Date();   //当前时间
        Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance(); //得到日历
        calendar.setTime(dNow);//把当前时间赋给日历
        calendar.add(Calendar.DAY_OF_MONTH, -1);  //设置为前一天
        dBefore = calendar.getTime();   //得到前一天的时间
        return dBefore;
    }

    public static String getDate(Date date) {
        return new SimpleDateFormat(SHORT_DATE_PATTERN).format(date);
    }

    /**
     * 把yyyymmdd的字符串转化为yyyy-mm-dd格式的日期
     *
     * @param str
     * @return
     */
    public static Date strToDate(String str) {
        if (null == str || "".equals(str) || str.length() < 1) {
            return new Date();
        }
        StringBuffer sb = new StringBuffer();
        String y = str.substring(0, 4);
        String m = str.substring(4, 6);
        String d = str.substring(6, 8);
        sb.append(y).append("-").append(m).append("-").append(d);
        return shortStringToDate(sb.toString());
    }

    /**
     * TODO 获取当月的第一天或最后一天
     *
     * @param a=0,b=1 当月第一天
     * @param a=1,b=0 当月最后一天
     * @return
     * @author lsy
     * 2017年2月28日 上午10:49:31
     */
    public static String monthFirstOrLast(int a, int b) {
        Calendar cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, a);
        cale.set(Calendar.DAY_OF_MONTH, b);
        return shortDateString(cale.getTime());
    }


    // 计算天数
    public static int dateBetween(Date early, Date late) {
        Calendar calst = Calendar.getInstance();
        Calendar caled = Calendar.getInstance();
        calst.setTime(early);
        caled.setTime(late);
        // 设置时间为0时
        calst.set(Calendar.HOUR_OF_DAY, 0);
        calst.set(Calendar.MINUTE, 0);
        calst.set(Calendar.SECOND, 0);
        caled.set(Calendar.HOUR_OF_DAY, 0);
        caled.set(Calendar.MINUTE, 0);
        caled.set(Calendar.SECOND, 0);
        // 得到两个日期相差的天数
        int days = ((int) (caled.getTime().getTime() / 1000) - (int) (calst.getTime().getTime() / 1000)) / 3600 / 24;
        return days;
    }

    public static int daysBetween(String smdate, String bdate) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 判断两个时间段是否存在公共部门
     *
     * @param bto
     * @param oto
     * @param sto
     * @param edo
     * @return
     */
    public static Map<String, String> getAlphalDate(String bto, String oto, String sto, String edo) throws Exception {
        Map<String, String> map = new HashedMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 标准时间
        Date bt = sdf.parse(bto);
        Date ot = sdf.parse(oto);
        // 目标时间
        Date st = sdf.parse(sto);
        Date ed = sdf.parse(edo);
        long btlong = Math.min(bt.getTime(), ot.getTime());// 开始时间
        long otlong = Math.max(bt.getTime(), ot.getTime());// 结束时间
        long stlong = Math.min(st.getTime(), ed.getTime());// 开始时间
        long edlong = Math.max(st.getTime(), ed.getTime());// 结束时间
        // 具体算法如下
        // 首先看是否有包含关系
        if ((stlong >= btlong && stlong <= otlong) || (edlong >= btlong && edlong <= otlong)) {
            // 一定有重叠部分
            long sblong = stlong >= btlong ? stlong : btlong;
            long eblong = otlong >= edlong ? edlong : otlong;
            map.put("success", "true");
            map.put("startTime", sdf.format(sblong));
            map.put("endTime", sdf.format(eblong));
        } else {
            map.put("success", "false");
        }
        return map;
    }

    /**
     * 获取月末时间
     *
     * @param time
     * @return
     * @throws Exception
     */
    public static String getMaxMonthDate(String time) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateFormat.parse(time));
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return dateFormat.format(calendar.getTime());
    }

    /**
     * 获取某年第一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 获取某年最后一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();

        return currYearLast;
    }

}
